#include "RoundQueue.hpp"
#include "Task.hpp"
#include <time.h>
#include <unistd.h>
template<class T>
struct PthreadDate
{
    RoundQueue<Task<T>>* _rq;
    std::string _s;
};
void *produre(void *args)
{
    PthreadDate<int> *pd = static_cast< PthreadDate<int> *>(args);
    while (true)
    {
        // 生产任务
        sleep(2);
        Task<int> t(rand() % 20, rand() % 21, Task<int>::get_op()[rand() % Task<int>::get_op().size()]);
        pd->_rq->push(t);
        pd->_s=std::to_string(pthread_self());

        std::cout <<"线程: "<<pd->_s<<" "<<"创建了一个任务: " << t.getresult() << std::endl;
    }
}
void *consumption(void *args)
{
    PthreadDate<int> *pd = static_cast< PthreadDate<int> *>(args);
    while (true)
    {
        sleep(1);
        // 拿到任务
        Task<int> t = pd->_rq->pop();
        pd->_s=std::to_string(pthread_self());
        t();
        // 消费任务
        std::cout <<"线程: "<<pd->_s<<" "<<"消费了一个任务: " << t.getresult() << std::endl;
    }
}
void create_pthread(pthread_t *cid, pthread_t *pid, RoundQueue<Task<int>> *&rq)
{

    for (int j = 0; j < 3; j++)
    {
        PthreadDate<int>* pd = new PthreadDate<int>();
        pd->_rq=rq;
        int ret2 = pthread_create(pid+j, NULL, produre, pd);
        if (ret2 == 0)
            std::cout <<"produre pthread creadte success" << std::endl;
        else
        {
            perror("produre pthread creadte fail");
            exit(PTHREAD_CREATE_FAIL);
        }
    }
    for (int i = 0; i < 3; i++)
    {
        PthreadDate<int>* pd = new PthreadDate<int>();
        pd->_rq=rq;
        int ret1 = pthread_create(cid + i, NULL, consumption, pd);
        if (ret1 == 0)
            std::cout <<"consumptoin pthread creadte success" << std::endl;
        else
        {
            perror("consumptoin pthread creadte fail");
            exit(PTHREAD_CREATE_FAIL);
        }
    }

}
int main()
{
    srand(time(nullptr));
    // 创建消费生产线程
    pthread_t cid[5], pid[3];
    RoundQueue<Task<int>>* rq=new RoundQueue<Task<int>>();
    create_pthread(cid, pid, rq);
    for(int i=0;i<5;i++)
    {
        pthread_join(cid[i], nullptr);
    }
    for(int j=0;j<3;j++)
    {
        pthread_join(pid[j], nullptr);
    }
    delete rq;
    return 0;
}